<?php

namespace App\Http\Controllers\Laifei\Work;

use App\Http\Controllers\Controller;
use App\Models\Common\Common;
use App\Models\Common\Wechat;
use App\Models\ProxyMember;
use App\Models\Tools\Data;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class LaifeiWorkSettlementController extends Controller
{
    protected $work_id;
    protected $settlement;
    protected $settlement_remark;
    protected $settlement_amount;

    public function index()
    {

        $all = $this->all;

        if (!isset($all['work_id']) || !isset($all['settlement']) || !isset($all['settlement_remark']) || !isset($all['settlement_amount'])) {
            return $this->setReturnJson(-1, '缺少参数');
        }
        if (!is_int($all['work_id'])) {
            return $this->setReturnJson(-1, '错误的参数类型');
        }

        $this->work_id = $all['work_id'];
        $this->settlement = $all['settlement'];
        $this->settlement_remark = $all['settlement_remark'];
        $this->settlement_amount = $all['settlement_amount'];

        /**
         * 允许结算
         */
        if($this->settlement){
            $result = self::settlement();
        } else { // 拒回结算，退回待投稿阶段
            $result = self::reject();
        }
        return $this->setReturnJson(...$result);

    }

    // 结算
    private function settlement()
    {

        // 商户订单号
        $mchBillNo = self::billNo($this->work_id);
        // 验证工单状态，提现金额
        try {
            DB::beginTransaction();
            // 工单加写锁
            $work_message = DB::table('explore_work')
                ->where('work_id', '=', $this->work_id)
                ->lockForUpdate()
                ->first();
            $work_message = json_decode(json_encode($work_message), true);

            // 订单加写锁
            $order_message = DB::table('explore_order')
                ->where('eo_id','=',$work_message['eo_id'])
                ->lockForUpdate()
                ->first();
            $order_message = json_decode(json_encode($order_message),true);

            // 用户信息加共享锁
            $openid = DB::table('lottery_users')
                ->where('we_id','=',$work_message['receiver_we_id'])
                ->sharedLock()
                ->value('openid');

            // 查询探店佣金比例
            $service_fee_percent = DB::table('sys_setting')
                ->where('setting_key','=','service_fee')
                ->sharedLock()
                ->value('setting_value');
            // 服务费
            $service_fee = ceil($work_message['settlement_amount'] * $service_fee_percent / 100);
            // 红包金额
            $payment_amount = $work_message['settlement_amount'] - $service_fee;

            // 验证金额
            if($this->settlement_amount !== $work_message['settlement_amount']){
                DB::rollBack();
                return [-1,'金额错误，请重试'];
            }

            // 验证当前工单状态，是否为待结算
            if($work_message['status'] !== Data::DATA_DB_EXPLORE_WORK_STATUS_CHECK){
                DB::rollBack();
                return [-1,'工单的当前状态不是待结算，请刷新当前页面重试'];
            }

            // 验证用户当日领取红包金额/数量是否超限
            $settlements = DB::table('explore_settlement')
                ->where('we_id','=',$work_message['receiver_we_id'])
                ->whereBetween('created_at', [date('Y-m-d').' 00:00:00', date('Y-m-d').' 23:59:59'])
                ->get()
                ->toArray();
            $settlements = json_decode(json_encode($settlements),true);
            if(count($settlements)>10){
                DB::rollBack();
                return [-1,'该用户今日领取红包数量超限，每日最高领取10个红包'];
            }
            if(array_sum(array_column($settlements,'amount'))>100000){
                DB::rollBack();
                return [-1,'该用户今日领取金额超限，每日最高领取1000元红包'];
            }

            // 检查订单是否已经完成:订单已经分发完成，且分发数=已完成数
            if (($order_message['remaining_num'] === 0) && $order_message['distribution_num'] === ($order_message['success_num']+1)) {
                // 没有正在进行的订单且没有剩余订单，如果有为系统错误
                if($order_message['pending_num'] !== 1 || $order_message['remaining_num'] > 0){
                    DB::rollBack();
                    Log::emergency('订单结算数据异常：'.LaifeiWorkSettlementController::class,['order_message'=>$order_message,'work_message'=>$work_message]);
                    return [-1,'订单结算异常，请联系研发处理'];
                }
                // 没有问题，订单全部完成,修改订单状态
                DB::table('explore_order')
                    ->where('eo_id','=',$work_message['eo_id'])
                    ->update(['status'=>Data::DATA_DB_EXPLORE_ORDER_STATUS_FINISHED]);
                // 记录订单日志
                DB::table('explore_order_log')->insert([
                    'eo_id'=>$work_message['eo_id'],
                    'action'=>Data::DATA_DB_EXPLORE_ORDER_ACTION_FINISHED,//订单完成操作
                    'user_id'=>$this->userInfo['id'],
                ]);
            }

            // 修改工单状态
            DB::table('explore_work')->where('work_id', '=', $this->work_id)->update([
                'status'=>Data::DATA_DB_EXPLORE_WORK_STATUS_SETTLEMENT,
                'settlement_time'=>date('Y-m-d H:i:s'),
                'settlement_user'=>$this->userInfo['id'],
                'settlement_remark'=>$this->settlement_remark,
            ]);
            // 记录工单日志
            DB::table('explore_work_log')->insert([
                'work_id'=>$this->work_id,
                'action'=>Data::DATA_DB_EXPLORE_WORK_ACTION_SETTLEMENT,
                'user_id'=>$this->userInfo['id'],
                'remark'=>'管理员【'.$this->userInfo['name'].'】结算工单，并发送红包到用户微信账户。结算备注：'.$this->settlement_remark,
            ]);
            // 修改订单数量状态
            DB::table('explore_order')
                ->where('eo_id','=',$work_message['eo_id'])
                ->decrement('pending_num');
            DB::table('explore_order')
                ->where('eo_id','=',$work_message['eo_id'])
                ->increment('success_num');


            // 发送红包并记录账单
            $redpackData = [
                'mch_billno'   => $mchBillNo,
                'send_name'    => '来飞网',
                're_openid'    => $openid,
                'total_amount' => env('APP_ENV') === 'production'? $payment_amount: 100, // 单位为分，不小于100,开发环境默认价格为1元
                'wishing'      => '您在来飞网的投稿已经审核通过啦，您的稿费请查收~',
                'act_name'     => '达人探店',
                'remark'       => '欢迎关注来飞网',
            ];
            $payment = Wechat::payment();
            $redpack = $payment->redpack;
            $result = $redpack->sendNormal($redpackData);

            $insert = [
                'work_id'=>$this->work_id,
                'work_no'=>$work_message['work_no'],
                'mch_billno'=>$mchBillNo,
                'we_id'=>$work_message['receiver_we_id'],
                'openid'=>$openid,
                'total_amount'=>$work_message['settlement_amount'],
                'payment_amount'=>$payment_amount,
                'service_fee'=>$service_fee,
                'payment_account'=>1, // 1：伯乐天成、2：大悦
            ];
            if($result['result_code'] === 'SUCCESS'){ // 支付成功记录表格完成
                Log::notice('红包发送记录',['result'=>$result]);
                DB::table('explore_settlement')->insert($insert);
            } else { // 当状态为FAIL时，存在业务结果未明确的情况。所以如果状态是FAIL，请务必再请求一次查询接口[请务必关注错误代码（err_code字段），通过查询得到的红包状态确认此次发放的结果。]，以确认此次发放的结果。
                //记录FAIL
                Log::debug('红包支付状态FAIL,$mchBillNo为'.$mchBillNo.',即将重试');
                $result = $redpack->info($mchBillNo); // 再请求一次查询接口以确认此次发放的结果;
                if($result['result_code'] === 'SUCCESS'){ // 如果查询已经发放成功，继续后续流程
                    Log::notice('红包发送记录',['result'=>$result]);
                    DB::table('explore_settlement')->insert($insert);
                } else { // 确认发放失败
                    Log::error('红包发送失败',$result);
                    throw new \Exception($result['return_msg']);
                }
            }
            // 检查这个工单的发单人是否有代理，以及推广时间，如果存在比例，那么需要给代理分成
            $apply_user = DB::table('lottery_users')->where('we_id','=',$work_message['apply_we_id'])->first();
            $apply_user = json_decode(json_encode($apply_user), true);
            // 如果存在代理，计算返点:
            if(!is_null($apply_user['proxy'])){
                $proportion = ProxyMember::proportion($apply_user['proxy_at']);
                // 检查推荐时间，是否还有返利
                if($proportion > 0){
                    // 增加余额:
                    // 根据订单价格和返利比例，计算返利金额
                    $proxy_price = (int)floor($work_message['settlement_amount'] * $proportion);
                    DB::table('proxy_users')
                        ->where('we_id','=',$apply_user['proxy'])
                        ->increment('wallet',$proxy_price);
                    DB::table('proxy_log')->insert([
                        'type'=>3,
                        'proxy_we_id'=>$apply_user['proxy'],
                        'consumer_we_id'=>$work_message['apply_we_id'],
                        'payment'=>$work_message['settlement_amount'],
                        'proxy_price'=>$proxy_price,
                    ]);
                    // 给推荐人发送通知
                    ProxyMember::rebateNotice($apply_user['nickname'],$proxy_price,$apply_user['proxy']);
                }
            }

            DB::commit();
            return [0, '工单结算成功'];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error(LaifeiWorkSettlementController::class, ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]);
            return [-1, '结算失败：'.$e->getMessage(), ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]];
        }
    }

    // 拒回
    private function reject()
    {
        try{
            DB::beginTransaction();
            $work = DB::table('explore_work')->where('work_id', '=', $this->work_id)->lockForUpdate()->first();
            $work = json_decode(json_encode($work), true);

            if($work['status'] !== Data::DATA_DB_EXPLORE_WORK_STATUS_CHECK){
                return [-1,'结算失败，当前订单状态不是待结算状态，请刷新重试'];
            }
            DB::table('explore_work')
                ->where('work_id', '=', $this->work_id)
                ->update([
                    'status' => Data::DATA_DB_EXPLORE_WORK_STATUS_REFUSE,
                    'accept_user' => $this->userInfo['id'],
                    'accept_remark' => $this->settlement_remark,
                ]);
            DB::table('explore_work_log')->insert([
                'work_id' => $this->work_id,
                'action' => Data::DATA_DB_EXPLORE_WORK_ACTION_REFUSE,
                'user_id' => $this->userInfo['id'],
                'remark' => '管理员【' . $this->userInfo['name'] . '】结算拒回，结算备注：' . $this->settlement_remark,
            ]);
            // 完成拒回操作
            DB::commit();

            //  发送验收拒回微信通知（发送给达人）
            $data = [
                'first' => '您好，您的投稿信息不符合结算要求，现已驳回。',
                'keyword1' => '您提交的探店投稿不符合结算要求，现已驳回，请重新提交',
                'keyword2' => $this->userInfo['name'],
                'keyword3' => $this->settlement_remark,
                'keyword4' => date('Y-m-d'),
                'remark' => '点击链接重新提交投稿信息',
            ];
            // 发送通知
            // 查询接单人的openid
            $openid = DB::table('lottery_users')->where('we_id','=',$work['receiver_we_id'])->value('openid');
            Common::sendLaifeiMessage($openid,'work_reject',$data,'/talent/history?tab=1');

            return [0,'结算拒回成功，待重新投稿'];
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error(LaifeiWorkSettlementController::class, ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]);
            return [-1, '结算失败：'.$e->getMessage(), ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]];
        }
    }

    /**
     * 获取工单的商户订单号
     * @param $work_id
     * @return bool|mixed|string
     */
    public static function billNo($work_id)
    {
        try{
            DB::beginTransaction();
            $mch_id = env('WECHAT_PAYMENT_MCH_ID');
            $date = date('Ymd');

            // 查询今日最大单号的mch_billNo
            $max_work = DB::table('explore_work')
                ->where('mch_billno','like',$mch_id.$date.'%')
                ->whereNotNull('mch_billno')
                ->orderByDesc('mch_billno')
                ->first();
            $max_work = json_decode(json_encode($max_work), true);
            if(is_null($max_work)){ // 如果没有，新建一个
                $mch_billno = $mch_id.$date.env('WECHAT_PAYMENT_PREFIX').'000000001'; // mch_billno默认：($mch_id+$date+$prefix+000000001)
                DB::table('explore_work')->where('work_id','=',$work_id)->update(['mch_billno'=>$mch_billno]);
                DB::commit();
                return $mch_billno; // mch_billno默认：($mch_id+$date+$prefix+000000001)
            }
            // 今天最大的billno
            $mch_billno = $max_work['mch_billno'];
            if($max_work['work_id'] === $work_id) { // 当前工单就是最高的mch_id
                DB::commit();
                return $mch_billno;
            } else { // mch_id+1
                $prefix = substr($mch_billno,0,19);
                $no = substr($mch_billno,19); // 编号
                $no = str_pad($no + 1,9,'0',STR_PAD_LEFT);// 新单号+1
                $mch_billno = $prefix . $no;
                DB::table('explore_work')->where('work_id','=',$work_id)->update(['mch_billno'=>$mch_billno]);
                DB::commit();
                return $mch_billno;
            }
        }catch (\Exception $e){
            Log::error(LaifeiWorkSettlementController::class, ['msg' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]);
            DB::rollBack();
            return false;
        }
    }


}
